<template>
  <div>
    <input type="checkbox" @change="handleChange" :checked="isChecked" :id="id">
    <span class="checkbox"></span>
    <span class="text" s-if="text">{{text}}</span>
  </div>
</template>
<script>
export default {
  name: "checkbox",
  props: ["text", "id"],
  mounted() {
    if (this.$parent.onDispatch) {
      this.$on("checkStatus", this.$parent.onDispatch);
    }
  },
  data() {
    return {
      id: this.id,
      parent: null,
      subItems: [],
      isChecked: false
    };
  },
  methods: {
    // 设置元素 Indeterminate 状态，若为true，表示部分选中
    _setIndeterminate(bool) {
      document.getElementById(this.id).indeterminate = bool;
    },
 
    // 获取元素 Indeterminate 状态
    _getIndeterminate() {
      return document.getElementById(this.id).indeterminate;
    },
 
    // 将元素所有子元素的选中状态统一设置成该元素的选中状态 true/false
    _setAllSubItem(component, bool) {
      component.$children.map(i => {
        i.isChecked = bool;
        this._setAllSubItem(i, bool);
      });
    },
 
    onDispatch(val) {
      //不是根元素
      // console.log(this.$parent.$parent._uid);
      console.log(this);
      // 恢复默认状态
      this._setIndeterminate(false);
      // 如果子组件传过来的值是"indeterminate"，即子组件是部分选中状态，那么其父组件一定也是部分选中状态
      if (val == "indeterminate") {
        this._setIndeterminate(true);
        this.$emit("checkStatus", "indeterminate");
        return;
      }
      var subItems = this.$children;
      if (subItems.length > 0) {
        var check_num = 0;
        subItems.map(i => {
          // 或者如果子选项中有一个为indeterminate，那么其父组件也一定也是部分选中状态
          if (i._getIndeterminate()) {
            this._setIndeterminate(true);
            this.$emit("checkStatus", "indeterminate");
            return;
          }
          if (i.isChecked) {
            check_num++;
          }
        });
        if (check_num == subItems.length) {
          //选中子项目个数
          this.isChecked = true;
          this.$emit("checkStatus", true);
        } else if (check_num == 0) {
          this.isChecked = false;
          this.$emit("checkStatus", false);
        } else {
          this._setIndeterminate(true);
          this.$emit("checkStatus", "indeterminate");
        }
      }
    },
 
    handleChange() {
      this.isChecked = !this.isChecked;
      this.$emit("checkStatus", this.isChecked);
      if (this.isChecked) {
        this._setAllSubItem(this, true);
      } else {
        this._setAllSubItem(this, false);
      }
    }
  }
};